/**
 * 
 */
package qldc.pm.ksdl;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;

import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;

// TODO: Auto-generated Javadoc
/**
 * The Class BasePortlet.
 *
 * @author anpm
 * The Base Object is responsible for delivering request to predefined actions
 * Reference to qldc.pm.qlct.dktt.DangKyThuongTruPortlet and qldc.pm.qlct.dktt.actions.ThongTinCongDanAction as an example
 */
public abstract class BasePortlet extends MVCPortlet {
	
	/** The Constant LOG. */
	private static final Log LOG = LogFactoryUtil.getLog(BasePortlet.class);
	
	/** The mvc path. */
	private static String MVC_PATH = "mvcPath";
	
	@Override
	public void init() throws PortletException {
		super.init();
	}
	
	/* (non-Javadoc)
	 * @see com.liferay.util.bridges.mvc.MVCPortlet#doView(javax.portlet.RenderRequest, javax.portlet.RenderResponse)
	 */
	@Override
	public void doView(RenderRequest renderRequest,
			RenderResponse renderResponse) throws IOException, PortletException {
		if(!doFilter(renderRequest, renderResponse)){
			defaultProcess(renderRequest, renderResponse);
		}
		super.doView(renderRequest, renderResponse);
	}
	
	/* (non-Javadoc)
	 * @see com.liferay.util.bridges.mvc.MVCPortlet#processAction(javax.portlet.ActionRequest, javax.portlet.ActionResponse)
	 */
	@Override
	public void processAction(ActionRequest actionRequest,
			ActionResponse actionResponse) throws IOException, PortletException {
		if(!doFilter(actionRequest, actionResponse)){
			defaultProcess(actionRequest, actionResponse);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.liferay.util.bridges.mvc.MVCPortlet#serveResource(javax.portlet.ResourceRequest, javax.portlet.ResourceResponse)
	 */
	@Override
	public void serveResource(ResourceRequest resourceRequest,
			ResourceResponse resourceResponse) throws IOException,
			PortletException {
		if(!doFilter(resourceRequest, resourceResponse)){
			defaultProcess(resourceRequest, resourceResponse);
		}
	}

/**
 * The action filter by using mvcPath and javax.portlet.action parameter's name in each request
 *  If there is not any matched case, it will router the request to defaultProcess
 *
 * @param request the request
 * @param response the response
 * @return true, if successful
 */
	private boolean doFilter(PortletRequest request, PortletResponse response) {
		String mvcPath = ParamUtil.getString(request, MVC_PATH);
		String actionName = ParamUtil.getString(request, ActionRequest.ACTION_NAME.toString());
		if(!mvcPath.trim().isEmpty()){
			String actionHandler = getResourceActions().get(mvcPath);
			if(actionHandler != null){
				try {
					Class<?> clazz = Class.forName(actionHandler);
					
					Method method = null;
					
					if(request instanceof RenderRequest){
						method = clazz.getMethod(actionName, RenderRequest.class, RenderResponse.class);
					}else if(request instanceof ActionRequest){
						method = clazz.getMethod(actionName, ActionRequest.class, ActionResponse.class);
					}else{
						method = clazz.getMethod(actionName, ResourceRequest.class, ResourceResponse.class);
					}
					
					method.invoke(clazz, request, response);
					
					return true;
				} catch (Exception e) {
					LOG.error("Error message: " + e.getMessage(), e);
					return false;
				}
			}
		}
		
		return false;
	}
	
/**
 * ResourceAction work as a Map which contain information regarding between mvcPath and which action are able to handle.
 *
 * @return the resource actions
 */
	public abstract Map<String, String> getResourceActions();

/**
 * Default process steps of render request.
 *
 * @param renderRequest the render request
 * @param renderResponse the render response
 * @throws IOException Signals that an I/O exception has occurred.
 * @throws PortletException the portlet exception
 */
	public abstract void defaultProcess(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException;

/**
 * Default process steps of action request.
 *
 * @param actionRequest the action request
 * @param actionResponsee the action responsee
 * @throws IOException Signals that an I/O exception has occurred.
 * @throws PortletException the portlet exception
 */
	public abstract void defaultProcess(ActionRequest actionRequest,ActionResponse actionResponsee) throws IOException, PortletException;

/**
 * Default process steps of resource request.
 *
 * @param resourceRequest the resource request
 * @param resourceResponse the resource response
 * @throws IOException Signals that an I/O exception has occurred.
 * @throws PortletException the portlet exception
 */
	public abstract void defaultProcess(ResourceRequest resourceRequest,ResourceResponse resourceResponse) throws IOException, PortletException;
}
